<?php
/**
 * GeryEngine
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this release in the file LICENSE
 *
 * @copyright  Copyright (c) 2007 Arjen Brouwer
 * @license    New BSD License
 * @author     Arjen Brouwer
 */

class FileResourceLoader extends ResourceLoader
{
	
	/**
	 * The GeryEngine used for logging
	 * @var GeryEngine
	 */
	private $engine;
	
    /**
     * The paths to search for templates.
     * @var array
     */
    private $paths = null;

    /**
     * The scheme this ResourceLoader is listening to
     * @var string
     */
    private $scheme;
    
    /**
     * Whether or not caching of the compiled templates is allowed or not
     *
     * @var boolean
     */
    private $cacheEnabled;
    
    public function __construct() {
    	
    }
    
	public function init(Properties $configuration, GeryEngine $engine)
    {
    	$this->engine = $engine;
    	
    	$engine->info("FileResourceLoader: initialization starting.");
        
        $this->paths = $configuration->getArray('path');
        
        /*
         * Lets tell people what paths we will be using
         */
        foreach ($this->paths as $path)
        {
        	$engine->info("FileResourceLoader: adding path '" . $path . "'");
        }
        
        /*
         * Set the scheme of this loader
         */
        $scheme = $configuration->getString('scheme');
        
        if (! strlen($scheme) || ! ctype_alpha($scheme)) {
        	
        	/*
        	 * Invalid scheme name specified
        	 */
        	
        	$msg = "Problem initializing resource loader: " . get_class($this) . ".\n"
            	. "Invalid scheme name specified: '{$scheme}'.";
            	
            $engine->error($msg);
            
            throw new Exception($msg);	
        }
        
        $this->scheme = $scheme;
        
        /*
         * Check if the templates compiled from the loaded resources may be cached
		 */
        $this->cacheEnabled = $configuration->getBoolean('cache');
         
        $engine->info("FileResourceLoader: initialization complete.");
    }
    
    /**
     * Get the scheme of this ResourceLoader is registered to
     *
     * @return string
     */
    public function getScheme() {
    	return $this->scheme;
    }
    
    /**
     * Whether or not the given resource is cachable
     *
     * @param Resource $resource
     * @return boolean True if the given resource is cachable, False otherwise
     */
    public function isResourceCachable(Resource $resource) {
    	return $this->cacheEnabled;
    }
   
    /**
     * Get an string so that the Runtime can build a
     * template with it.
     *
     * @param string $templateName name of template to get
     * @return string containing the template
     * @throws ResourceNotFoundException if template not found
     *         in the file template path.
     */
    public function getResource($templateName)
    {	
        /*
         * Make sure we have a valid templateName.
         */
        if (! strlen($templateName))
        {
            /*
             * If we don't get a properly formed templateName then
             * there's not much we can do. So we'll forget about
             * trying to search any more paths for the template.
             */
            throw new GeryResourceNotFoundException("Need to specify a file name or file path!");
        }

        $template = FileUtil::normalizePath($templateName);
        
        if (! strlen($template))
        {
            $msg = "File resource error: argument " . $templateName . 
                " contains .. and may be trying to access " .
                "content outside of template root.  Rejected.";

            $this->engine->error("FileResourceLoader : " . $msg);
      
            throw new GeryResourceNotFoundException($msg);
        }

        /*
         *  if a / leads off, then just nip that :)
         */
        if (substr($template, 0, 1) == "/")
        {
            $template = substr($template, 1);
        }

        foreach ($this->paths as $path) 
        {
        	$file = $path . '/' . $template;
        	
        	if (file_exists($file) && is_file($file))
        	{
        		$resource = new Resource(
                	$templateName
                	,file_get_contents($file)
                	,filemtime($file)
                	,$this);
                	
        		return $resource;
            }                
        }
    
        /*
         * We have now searched all the paths for
         * templates and we didn't find anything so
         * throw an exception.
         */
         $msg = "FileResourceLoader Error: cannot find resource " . $template;
         
         throw new GeryResourceNotFoundException($msg);
    }
}
